package com.guet.service.impl;

import com.fasterxml.jackson.databind.ser.Serializers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.guet.DTO.PaperDTO;
import com.guet.DTO.PaperPageDTO;
import com.guet.DTO.QuestionsDTO;
import com.guet.DTO.QuestionsSaveDTO;
import com.guet.Entity.*;
import com.guet.VO.*;
import com.guet.context.BaseContext;
import com.guet.mapper.StatisticsMapper;
import com.guet.mapper.TestMapper;
import com.guet.result.PageResult;
import com.guet.service.StatisticsService;
import com.guet.service.TestService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
@Slf4j
public class TestServiceImpl implements TestService {
    @Autowired
    private TestMapper testMapper;
    @Autowired
    private StatisticsMapper statisticsMapper;

    @Override
    @Transactional
    public Integer savePaper(PaperDTO paperDTO) {
        Long userId = BaseContext.getCurrentId();
        LocalDateTime beginTime = LocalDateTime.of(paperDTO.getBeginTime(), LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(paperDTO.getEndTime(), LocalTime.MAX);
        Paper paper = new Paper();

        // 判断是否为新增
        if (paperDTO.getId() == null || paperDTO.getId().toString().trim().isEmpty()) {
            // 第一次添加试卷，没有 ID
            BeanUtils.copyProperties(paperDTO, paper);
            paper.setUserId(userId);
            paper.setStatus(0); // 0 代表未发布
            paper.setBeginTime(beginTime);
            paper.setEndTime(endTime);

            // 插入试卷并返回主键 ID
            testMapper.insertPaper(paper);
            return paper.getId(); // 回显试卷 ID
        } else {
            // 修改或重新添加试卷，先删除旧数据
            Integer paperId = paperDTO.getId();
            testMapper.deletePaperById(userId, paperId);

            // 获取试卷下的题目
            List<Questions> questionsList = testMapper.queryQuestionsByPaperId(paperId);

            // 删除试卷下的题目及关联数据
            testMapper.deleteQuestionsByPaperId(paperId);
            for (Questions questions : questionsList) {
                Integer questionId = questions.getId();
                // 删除题目下的选项和正确答案
                testMapper.deleteOptionsByQuestionId(questionId);
                testMapper.deleteCorrectAnswerByQuestionId(questionId);
            }

            // 插入新的试卷数据
            BeanUtils.copyProperties(paperDTO, paper);
            paper.setUserId(userId);
            paper.setStatus(0); // 未发布状态
            paper.setBeginTime(beginTime);
            paper.setEndTime(endTime);

            testMapper.insertPaper(paper);
            return paper.getId(); // 回显新的试卷 ID
        }
    }


    /**
     * 分页查询试卷
     *
     * @param paperPageDTO
     * @return
     */
    @Override
    public PageResult getPaperList(PaperPageDTO paperPageDTO) {
        PageHelper.startPage(paperPageDTO.getCurrentPage(), paperPageDTO.getPageSize());
        Page<PaperVO> result = testMapper.list(paperPageDTO);
        Long total = result.getTotal();
        List<PaperVO> paperList = result.getResult();
        return new PageResult(total, paperList);
    }

    /**
     * 插入题目和选项
     *
     * @param questionsDTOList
     * @param paperId
     */
    @Override
    @Transactional
    public void saveQuestions(List<QuestionsDTO> questionsDTOList, Integer paperId) {
        for (QuestionsDTO questionsDTO : questionsDTOList) {
            // 1. 保存题目数据
            Questions question = new Questions();
            question.setTitle(questionsDTO.getTitle());
            question.setExplanation(questionsDTO.getExplanation());
            question.setCreateTime(LocalDateTime.now());
            question.setUpdateTime(LocalDateTime.now());
            question.setCorrectAnswer(questionsDTO.getCorrectAnswer());
            question.setPaperId(paperId);

            // 插入题目并返回题目的 ID
            testMapper.insertQuestion(question);

            // 2. 保存选项数据
            Map<String, String> options = questionsDTO.getOptions();
            for (Map.Entry<String, String> entry : options.entrySet()) {
                Options option = new Options();
                option.setQuestionId(question.getId());  // 设置选项对应的题目 ID
                option.setLabel(entry.getKey());         // 设置选项标签（如 A, B, C, D）
                option.setContent(entry.getValue());    // 设置选项内容

                // 插入选项
                testMapper.insertOption(option);
            }

            // 3. 处理正确答案
            if (questionsDTO.getCorrectAnswer() != null) {
                // 假设 correctAnswer 是选项的标签（例如 A、B、C），我们需要查询选项的 ID
                String correctAnswerLabel = questionsDTO.getCorrectAnswer();
                // 获取正确选项的 ID
                Integer correctOptionId = testMapper.queryOptionIdByLabelAndQuestionId(question.getId(), correctAnswerLabel);

                // 将正确答案插入正确答案表
                testMapper.insertCorrectAnswer(question.getId(), correctOptionId);
            }
        }
    }

    /**
     * 根据paperId获取题目和选项
     *
     * @param paperId
     * @return
     */
    @Override
    public List<QuestionsVO> queryQuestions(Integer paperId) {
        List<Questions> questionsList = testMapper.queryQuestionsByPaperId(paperId);
        List<QuestionsVO> questionsVOList = new ArrayList<>();

        for (Questions questions : questionsList) {
            QuestionsVO questionsVO = new QuestionsVO();
            // 获取正确答案
            String correctAnswer = testMapper.queryQuestionCorrectAnswer(questions.getId());
            BeanUtils.copyProperties(questions, questionsVO);  // 拷贝属性
            questionsVO.setCorrectAnswer(correctAnswer);  // 设置正确答案
            // 查询选项
            List<Options> options = testMapper.queryOptionsByQuestionId(questions.getId());
            // 使用一个 Map 来存储选项
            Map<String, String> optionMap = new HashMap<>();

            for (Options option : options) {
                String label = option.getLabel();
                String content = option.getContent();
                optionMap.put(label, content);  // 将选项添加到 Map 中
            }
            // 设置所有选项
            questionsVO.setOptions(optionMap);
            // 将当前的 questionsVO 加入列表
            questionsVOList.add(questionsVO);
        }
        return questionsVOList;
    }

    /**
     * 通过id查询试卷信息
     *
     * @param id
     * @return
     */
    @Override
    public PaperVO getPaperById(Integer id) {
        return testMapper.queryPageById(id);
    }

    /**
     * 根据id删除试卷
     *
     * @param id
     */
    @Override
    @Transactional
    public void deletePaperById(Integer id) {
        Long userId = BaseContext.getCurrentId();
        testMapper.deletePaperById(userId, id);
        List<Questions> questionsList = testMapper.queryQuestionsByPaperId(id);
        testMapper.deleteQuestionsByPaperId(id);
        for (Questions questions : questionsList) {
            Integer questionId = questions.getId();
            testMapper.deleteOptionsByQuestionId(questionId);
            testMapper.deleteCorrectAnswerByQuestionId(questionId);
        }
    }

    /**
     * 发布试卷
     *
     * @param id
     */
    @Override
    public void publishPaper(Integer id) {
        Long userId = BaseContext.getCurrentId();
        Integer status = 1;
        testMapper.updateStatus(id, userId, status);
    }

    /**
     * 获取试卷的题目和选项
     *
     * @param id
     * @return
     */
    @Override
    public List<QuestionsForStuVO> getQuestionList(Integer id) {
        List<Questions> questionsList = testMapper.queryQuestionsByPaperId(id);
        List<QuestionsForStuVO> questionsForStuVOList = new ArrayList<>();
        for (Questions questions : questionsList) {
            QuestionsForStuVO questionsForStuVO = new QuestionsForStuVO();
            Integer questionId = questions.getId();
            List<Options> options = testMapper.queryOptionsByQuestionId(questionId);
            Map<String, String> optionMap = new HashMap<>();
            for (Options option : options) {
                String label = option.getLabel();
                String content = option.getContent();
                optionMap.put(label, content);
            }
            BeanUtils.copyProperties(questions, questionsForStuVO);
            questionsForStuVO.setOptions(optionMap);
            questionsForStuVOList.add(questionsForStuVO);
        }

        return questionsForStuVOList;
    }

    /**
     * 保存学生的作答记录
     *
     * @param questionsSaveDTO 学生作答数据
     * @param paperId          试卷 ID
     */
    @Override
    @Transactional
    public void saveAnswer(QuestionsSaveDTO questionsSaveDTO, Integer paperId) {
        Long userId = BaseContext.getCurrentId();
        LocalDateTime submitTime = LocalDateTime.now();

        // 查询是否已存在答卷
        StuAnswerPaper stuAnswerPaper = testMapper.queryStuAnswerPaperById(paperId, userId);
        if (stuAnswerPaper != null) {
            // 删除旧答卷及答题记录
            testMapper.deleteStuAnswerPaper(stuAnswerPaper.getId());
            testMapper.deleteStuAnswerQuestion(stuAnswerPaper.getId());
        }

        // 插入新的答卷
        stuAnswerPaper = StuAnswerPaper.builder()
                .paperId(paperId)
                .userId(userId)
                .submitTime(submitTime)
                .build();
        testMapper.insertStuAnswerPaper(stuAnswerPaper);
        Integer stuAnswerPaperId = stuAnswerPaper.getId();

        // 构建答题记录并批量插入
        List<StuAnswerQuestion> questions = new ArrayList<>();
        Map<Integer, String> answers = questionsSaveDTO.getAnswers();
        for (Map.Entry<Integer, String> entry : answers.entrySet()) {
            Integer questionId = entry.getKey(); // 题目 ID
            String label = entry.getValue();    // 答案选项
            StuAnswerQuestion question = StuAnswerQuestion.builder()
                    .stuAnswerPaperId(stuAnswerPaperId)
                    .questionId(questionId)
                    .answer(label)
                    .submitTime(submitTime)
                    .build();
            questions.add(question);
        }

        // 批量插入
        if (!questions.isEmpty()) {
            testMapper.batchInsertStuAnswerQuestions(questions);
        }
    }

    /**
     * 获取作答记录
     *
     * @param paperId
     * @return
     */
    @Override
    public Map<Integer, String> getAnswer(Integer paperId) {
        Long userId = BaseContext.getCurrentId(); // 获取当前用户 ID
        List<Map<String, Object>> answers = testMapper.queryAnswerById(paperId, userId);

        // 将结果转换为 Map<Integer, String>
        return answers.stream()
                .collect(Collectors.toMap(
                        answer -> (Integer) answer.get("question_id"),
                        answer -> (String) answer.get("answer")
                ));
    }

    /**
     * 计算分数
     */
    @Transactional
    public void computeScore(Integer paperId) {
        Long userId = BaseContext.getCurrentId();
        List<Questions> questionsList = testMapper.queryQuestionsByPaperId(paperId);
        double questionScore = BigDecimal.valueOf(100)
                .divide(BigDecimal.valueOf(questionsList.size()), 2, RoundingMode.HALF_UP)
                .doubleValue();
        double score = 0;
        for (Questions questions : questionsList) {
            Integer questionId = questions.getId();
            String correctAnswer = testMapper.queryCorrectAnswerLabelByQuestionId(questionId);
            String userAnswer = testMapper.queryUserAnswer(paperId, userId, questionId);
            // 回答正确
            if (correctAnswer.equals(userAnswer)) {
                score += questionScore;
            }
        }
        Score build = Score.builder().userId(userId).paperId(paperId).score(score).build();
        testMapper.insertStuScore(build);
    }

    /**
     * 根据试卷id查询正确选项和解析
     * @param id
     * @return
     */
    @Override
    public List<CorrectAnswerVO> getCorrectAnswer(Integer id) {
        List<Questions> questionsList = testMapper.queryQuestionsByPaperId(id);
        List<CorrectAnswerVO> correctAnswerVOS = new ArrayList<>();
        for (Questions questions : questionsList){
            CorrectAnswerVO correctAnswerVO = new CorrectAnswerVO();
            Integer questionId = questions.getId();
            String correctAnswer = testMapper.queryCorrectAnswerLabelByQuestionId(questionId);
            correctAnswerVO.setQuestionsId(questionId);
            correctAnswerVO.setCorrectOption(correctAnswer);
            correctAnswerVO.setExplanation(questions.getExplanation());
            correctAnswerVOS.add(correctAnswerVO);
        }
        return correctAnswerVOS;
    }

    /**
     * 获取学生作答分数
     * @param id
     * @return
     */
    @Override
    public String getScore(Integer id) {
        Long userId = BaseContext.getCurrentId();
        return statisticsMapper.getScore(userId, id);
    }

}


